// #### 1.3 使用构造函数
function Person(name, age) {
  this.name = name;
  this.age = age;
}
const person = new Person("Alice", 25);

// #### 2.3 使用 `Object.defineProperty()`
const obj = {};
Object.defineProperty(obj, "key", {
  value: "value",
  writable: true, // 是否可修改
  enumerable: true, // 是否可枚举
  configurable: true // 是否可配置
});

// #### 3.1 使用 `in` 操作符
const obj = { key: "value" };
console.log("key" in obj); // true
console.log("nonExistentKey" in obj); // false


// #### 3.2 使用 `hasOwnProperty()`
const obj = { key: "value" };
console.log(obj.hasOwnProperty("key")); // true
console.log(obj.hasOwnProperty("nonExistentKey")); // false

// #### 4.1 使用 `for
const obj = { key1: "value1", key2: "value2" };
for (const key in obj) {
  if (obj.hasOwnProperty(key)) { // 排除原型链上的属性
    console.log(key, obj[key]);
  }
}


// #### 4.2 使用 `Object.keys()` 和 `Object.values()` 和 `Object.entries()`

const obj = { key1: "value1", key2: "value2" };

// 获取对象的键
const keys = Object.keys(obj); // ["key1", "key2"]
keys.forEach((key) => {
  console.log(key, obj[key]);
});

// 获取对象的值
const values = Object.values(obj); // ["value1", "value2"]
values.forEach((value) => {
  console.log(value);
});

// 获取对象的键值对
const entries = Object.entries(obj); // [["key1", "value1"], ["key2", "value2"]]
entries.forEach(([key, value]) => {
  console.log(key, value);
});


// ### 5添加和删除属性
// #### 5.1 添加属性
const obj = {};
obj.newKey = "newValue"; // 使用点符号
obj["anotherKey"] = "anotherValue"; // 使用方括号语法


// #### 5.2 删除属性
const obj = { key: "value" };
delete obj.key; // 删除属性
console.log(obj); // {}


// ### 6 其他对象方法

// #### 6.1 `Object.assign()`
// - **功能**：将一个或多个源对象的所有可枚举属性复制到目标对象中，并返回目标对象。
// - **语法**：
  Object.assign(target, ...sources)
  
// - **示例**：
  const target = { a: 1 };
  const source1 = { b: 2 };
  const source2 = { c: 3 };
  const result = Object.assign(target, source1, source2);
  console.log(result); // { a: 1, b: 2, c: 3 }
  

// #### 6.2 `Object.freeze()`
// - **功能**：冻结一个对象，使其不可修改。
// - **语法**：
  Object.freeze(obj)
  
// - **示例**：
  const obj = { key: "value" };
  Object.freeze(obj);
  obj.key = "newValue"; // 无法修改
  console.log(obj); // { key: "value" }
  

// #### 6.3 `Object.seal()`
// - **功能**：密封一个对象，使其不能添加或删除属性，但可以修改现有属性的值。
// - **语法**：
  Object.seal(obj)
  
// - **示例**：
  const obj = { key: "value" };
  Object.seal(obj);
  obj.key = "newValue"; // 可以修改值
  delete obj.key; // 无法删除
  console.log(obj); // { key: "newValue" }
  

// #### 6.4 `Object.preventExtensions()`
// - **功能**：防止对象添加新属性，但可以修改现有属性的值。
// - **语法**：
  Object.preventExtensions(obj)
  
// - **示例**：
//   const obj = { key: "value" };
  Object.preventExtensions(obj);
  obj.key = "newValue"; // 可以修改值
  obj.newKey = "newVal"; // 无法添加新属性
  console.log(obj); // { key: "newValue" }
  

// #### 6.5 `Object.is()`
// - **功能**：比较两个值是否严格相等，与 `===` 类似，但更严格（例如可以区分 `+0` 和 `-0`）。
// - **语法**：
  Object.is(value1, value2)
  
// - **示例**：
  console.log(Object.is(+0, -0)); // false
  console.log(Object.is(NaN, NaN)); // true
  

// ### 7\. 对象的原型和继承

// #### 7.1 `Object.getPrototypeOf()` 和 `Object.setPrototypeOf()`
// - **`Object.getPrototypeOf(obj)`**：获取对象的原型。
// - **`Object.setPrototypeOf(obj, prototype)`**：设置对象的原型。
  const obj = {};
  const prototype1 = { inheritedKey: "inheritedValue" };
  Object.setPrototypeOf(obj, prototype1);
  console.log(obj.inheritedKey); // "inheritedValue"
  

// #### 7.2 `Object.create()`
// - **功能**：创建一个新对象，并指定其原型。
// - **语法**：
  Object.create(prototype[ prototype, propertiesObject])

  const prototype = { inheritedKey: "inheritedValue" };
  const obj = Object.create(prototype);
  console.log(obj.inheritedKey); // "inheritedValue"
